"""
Created on 18-Dec-2009

@author: dexen
"""

import time
import threading 

from dexen.system.server.info import MasterInfo, SlaveInfo

RUNNING = 1
STOPPED = 2
PAUSED = 3

# TODO: ensure the release of locks during failure.
class MasterComm(object):    
    def __init__(self, name):
        self.slave_name = None
        self.lock = threading.Lock()
        self.master_info = MasterInfo(name)
        self._has_unit = False
        self.state = RUNNING
        """ 
        slaves_info only contains the info object of slaves that are
        either crashed or completed.
        So, it does not maintain the running slaves
        """
        self.slaves_info = {}
    
    def stopping(self):
        with self.lock:
            self.state = STOPPED
        
    def can_schedule(self):
        with self.lock:
            return self.slave_name == None and self._has_unit and self.state == RUNNING
    
    def has_unit(self, flag=None):
        with self.lock:
            if flag != None:
                self._has_unit = flag
                return
            return self._has_unit 
    
    def update_slave(self, slave):
        with self.lock:
            assert  isinstance(slave, SlaveInfo)
            self.slaves_info[slave.name] = slave        
                 
    def put_slave(self, slave_name):
        with self.lock:
            self.slave_name = slave_name
        
    def get_slave(self):
        """
        This method would be made sure to call when there is already unit
        in other words, self._has_unit is True.
        """
        with self.lock:
            if self.slave_name:
                self._has_unit = False # Important
                res = self.slave_name
                self.slave_name = None
                return res
            else: 
                return None
         
    def get_info(self):
        with self.lock:
            if self.slave_name == None and self._has_unit:
                self.master_info.can_schedule(True)
            else:
                self.master_info.can_schedule(False)    
            
            slaves_info = self.slaves_info.values() # list vs dict?
            self.slaves_info = {} # Note I am removing all the slaves
            return self.master_info, slaves_info



